package com.haredot.controller;

import com.aliyun.oss.OSS;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.PutObjectRequest;
import com.haredot.dto.FindPwdDTO;
import com.haredot.oss.properties.OssProperties;
import com.haredot.service.UserService;
import com.haredot.vo.R;
import com.haredot.vo.UserOneVo;
import com.haredot.vo.UserThreeVo;
import com.haredot.vo.UserTwoVo;
import org.apache.commons.io.IOUtils;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.http.HttpEntity;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.InputStream;
import java.net.URI;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.UUID;

@RestController
@EnableConfigurationProperties({OssProperties.class})
public class LoginController {

    @Resource
    private UserService userService ;

    @Resource
    private OssProperties ossProperties ;

    @Resource
    private OSS ossClient ;
    /**
     * 注册第一步
     * @param userOneVo
     * @return
     */
    @PostMapping("/register")
    public R<?> register(@RequestBody @Valid UserOneVo userOneVo) {
        return userService.registerOne(userOneVo) ;
    }
    /**
     * 注册第二步
     * @param userTwoVo
     * @return
     */
    @PutMapping("/register/{uid}")
    public R<?> register(@PathVariable("uid") Long userId, @RequestBody @Valid UserTwoVo userTwoVo) {
        return userService.registerTwo(userTwoVo) ;
    }

    /**
     * 注册第三步，激活发送邮件
     * @return
     */
    @PutMapping("/register")
    public R<?> register(@RequestBody @Valid UserThreeVo userThreeVo, @RequestHeader("Referer") String referer) {
        userThreeVo.setReferer(referer);
        return userService.registerThree(userThreeVo) ;
    }

    @GetMapping("/activeAccount/{uid}")
    public Object activeAccount(@PathVariable("uid") Long uid,
                                      @RequestParam("code") String code ,
                                      @RequestParam("_time") String time,
                                      @RequestParam("referer") String referer,
                                      @RequestParam("sign")String sign) {

        Map<String, Object> params = Map.of("uid", uid, "code", code, "time", time, "sign", sign);

        R<?> ret = userService.active(params) ;
        // 如果激活成功，则跳回到 前端登录页面
        if(ret.getStatus()) {
            URI uri = URI.create(URLDecoder.decode(referer, StandardCharsets.UTF_8));
            String redirectUrl = uri.getScheme() + "://" + uri.getHost() + (uri.getPort()!= -1 ? ":" + uri.getPort() : "") + "/login?f=success" ;
            return new ModelAndView("redirect:" + redirectUrl) ;
        }
        // 否则返回激活失败的原因
        return ret ;
    }


    @PostMapping("/upload")
    public R<?> upload(@RequestPart("avatar") MultipartFile part) throws Exception {
        // 获取 要存储在 磁盘上的文件名
        String filename = "avatar/" + UUID.randomUUID() + part.getOriginalFilename();
        // 构建 PutObjectRequest对象
        PutObjectRequest putObjectRequest = new PutObjectRequest(ossProperties.getBucketName(), filename, part.getInputStream());
        // 上传文件到网盘
        ossClient.putObject(putObjectRequest);
        // 返回结果
        return R.ok().data(filename);
    }


    @GetMapping(value = "/preview", produces = MediaType.IMAGE_JPEG_VALUE)
    public HttpEntity<byte[]> preview(@RequestParam("path") String objectName,
                                      @RequestParam(value = "type", required = false, defaultValue = "attachment") String type) throws Exception {

        OSSObject object = ossClient.getObject(new GetObjectRequest(ossProperties.getBucketName(), objectName));
        // 获取 OSS 中对应的文件内容
        try(InputStream objectContent = object.getObjectContent()) {
            // 转成 byte[] 数组
            byte[] bytes = IOUtils.toByteArray(objectContent);
            // 截取获取原上传的文件名
            int index = objectName.lastIndexOf("/");
            String downloadName = objectName.substring(index + 37);
            // 对文件名(包含中文)进行URL编码
            String encode = URLEncoder.encode(downloadName, StandardCharsets.UTF_8);

            if (!"attachment".equals(type)) type = "inline";
            // 下载文件
            return ResponseEntity
                    .ok()
                    .header("Content-Disposition", type + ";filename=" + encode)
                    .body(bytes);
        }catch (Exception e) {
            e.printStackTrace();
            throw e ;
        }
    }

    /**
     * 邮箱登录 获取验证码
     */
    @PostMapping("/email/code")
    public R<?> emailCode(@RequestParam("email") String email,
                           @RequestParam("subject") String subject) {
        return userService.getEmailCode(email, subject) ;
    }

    @PutMapping("/login")
    public R<?> emailLogin(@RequestParam("email") String email, @RequestParam("code") String code) throws Exception {
        return userService.login(email, code) ;
    }


    @PutMapping("/bind/account")
    public R<?> bindAccount(@RequestParam("uid") String uid,
                            @RequestParam("type") String type,
                            @RequestParam("sign") String sign,
                            @RequestParam("tel") String tel,
                            @RequestParam("password") String password) {

        return userService.bindAccount(uid, type, sign, tel, password);
    }

    @PutMapping("/fwd")
    public R<?> findPassword(@RequestBody @Valid FindPwdDTO findPwdDTO) {

        // 调用业务逻辑层，处理业务
        return userService.findPasswordByEmail(findPwdDTO);
    }

}
